雖然在前往獨角獸的路上很忙,但是絕對不能少的就是測試。
好的測試可以讓你開發中,減少重工浪費時間的機率,也可以讓整個 continuous delivery 的機制更多了一點的信心
而且在開發的過程中,可以讓測試案例幫助釐清功能的驗證同時,也可以更快速的修正,提早搶先在前端串接前發現問題並且修正。
所以我選用了一個目前社群討論熱度高,且使用上友善很多的 PEST
官方有寫一篇簡短的介紹可以看看這個套件的優勢
以下是我針對開發 API 同時,先行設定好的幾個測試案例
describe('ChannelApi', function () {
it('should be able to get a list of channels', function () {
$response = $this->get('/api/channels');
$this->assertEquals(200, $response->getStatusCode());
$this->assertJsonResponse($response);
$this->assertCount(5, $response->json());
});
});
describe('ChannelApi', function () {
it('should be able to get the latest 10 channels with new episodes today', function () {
$response = $this->get('/api/channels/latest');
$this->assertEquals(200, $response->getStatusCode());
$this->assertJsonResponse($response);
$this->assertCount(10, $response->json());
});
});
describe('ChannelApi', function () {
it('should be able to get the channel with the most saved episodes today', function () {
$response = $this->get('/api/channels/most-saved');
$this->assertEquals(200, $response->getStatusCode());
$this->assertJsonResponse($response);
$this->assertEquals(1, $response->json()['id']);
$this->assertEquals(10, $response->json()['episodes_count']);
});
});
describe('EpisodeApi', function () {
it('should be able to get an episode by its ID', function () {
$response = $this->get('/api/episodes/EXnf2B');
$this->assertEquals(200, $response->getStatusCode());
$this->assertJsonResponse($response);
$this->assertEquals('http://localhost:8080/episode-1.mp4', $response->json()['guid']);
$this->assertEquals('Episode 1', $response->json()['title']);
});
});
describe('EpisodeApi', function () {
it('should be able to get the episode with the most saves today', function () {
$response = $this->get('/api/episodes/most-saved');
$this->assertEquals(200, $response->getStatusCode());
$this->assertJsonResponse($response);
$this->assertEquals(1, $response->json()['id']);
$this->assertEquals(10, $response->json()['saves_count']);
});
});
use App\Models\Channel;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(Tests\TestCase::class, RefreshDatabase::class);
it('does not create a channel without a name field', function () {
$response = $this->postJson('/api/channels', []);
$response->assertStatus(422);
});
it('can create a channel', function () {
$attributes = Channel::factory()->raw();
$response = $this->postJson('/api/channels', $attributes);
$response->assertStatus(201);
$this->assertDatabaseHas('channels', $attributes);
});
it('can fetch a channel', function () {
$channel = Channel::factory()->create();
$response = $this->getJson("/api/channels/{$channel->id}");
$data = [
'channel' => [
'id' => $channel->id,
'country' => $channel->country,
'cover_image' => $channel->cover_image,
'title' => $channel->title,
'slug' => $channel->slug,
'description' => $channel->description,
]
];
$response->assertStatus(200)->assertJson($data);
});
it('can update a channel', function () {
$channel = Channel::factory()->create();
$updatedChannel = ['id' => $channel->id];
$response = $this->putJson("/api/channels/{$channel->id}", $updatedChannel);
$response->assertStatus(200);
$this->assertDatabaseHas('channels', $updatedChannel);
});
it('can delete a channel', function () {
$channel = Channel::factory()->create();
$response = $this->deleteJson("/api/channels/{$channel->id}");
$response->assertStatus(200);
$this->assertCount(0, Channel::all());
});
以下是測試失敗時
這是測試都成功時
你以為只是在開發中幫 API 除錯,其實不知不覺中就已經把測試完成了呢!
提供一個給你相較於 Postman 之類的 API test client,已經整合在專案中的最佳選擇。
以上是這次實作的紀錄,如果有哪個部分需要解釋的部分,可以在留言處留下問題,我會盡量補充。